/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */
package jp.ize.ux;

import flash.events.FocusEvent;
import jp.ize.iwp.RuntimeEngine;

// {{{ class UXFocusManager
/** 
 * UXFocusManagerクラス<br>
 * フォーカス対象のオブジェクト配列を管理し、フォーカス対象が唯一になるよう管理するクラスです。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id$<br>
 */
class UXFocusManager
{
	// {{{ properties

	/** フォーカス管理の対象となるオブジェクト配列です。 */
	public var focusees : Array<UXObject>;
	/** 現在のフォーカスされているオブジェクトのフォーカス・インデックスです。 */
	public var focusIndex : Int;

	// {{{ public var cyclick(default, default) : Bool
	/**
	 * フォーカス移動を循環的にするかどうかのフラグです。デフォルトはtrueです。
	 */
	public var cyclick(default, default) : Bool;
	// }}}
	// }}}
	// {{{ public function new()
	/**
	 * コンストラクタ
	 */
	public function new()
	{
		focusees = new Array();
		focusIndex = 0;
		cyclick = true;
	}
	// }}}
	// {{{ public function addFocusee( fs : UXObject, ?fIndex:Int ) : Void
	/**
	 * 指定されたオブジェクトをフォーカス管理下に置きます。
	 */
	public function addFocusee( fs : UXObject, ?fIndex:Int ) : Void
	{
		if ( fIndex!=null ) {
			fs.focusIndex = fIndex;
		}
		fs.focusManager = this;
		focusees.push(fs);
	}
	// }}}
	// {{{ public function removeFocusee( fs : UXObject ) : Void
	/**
	 * 指定されたオブジェクトが管理下にあれば、そのオブジェクトを管理から外します。
	 */
	public function removeFocusee( fs : UXObject ) : Void
	{
		fs.focusManager = null;
		focusees.remove(fs);
	}
	// }}}
 	// {{{ public function getCurrentFocusee() : UXObject
	/**
	 * 現在フォーカスのあるオブジェクトを取得します。
	 */
	public function getCurrentFocusee() : UXObject
	{
		return focusees[focusIndex];
	}
	// }}}
	// {{{ public function sort() : Void
	/**
	 * 登録されているオブジェクトをfocusIndexの小さい順に(安定ソートで)並べます。この順番がフォーカス移動の
	 * 順番になります。
	 */
	public function sort() : Void
	{
		var comp = function(a:UXObject,b:UXObject):Int {
			if ( a.focusIndex==b.focusIndex ) {
				return 0;
			} else if ( a.focusIndex>b.focusIndex ) {
				return 1;
			} else {
				return -1;
			}
			return 0;
		}
		focusees.sort(comp);
	}
	// }}}
	// {{{ public function next() : Void
	/**
	 * focusIndex順にフォーカスを次へ移します。もし同じ数字のfocusIndexをもつオブジェクトが複数ある場合には、
	 * 配列に格納されている順番でフォーカスの移動先が決められます。
	 */
	public function next() : Void
	{
		/* UXObjectのputEventメソッドにFocusEventイベントを投げます*/
		focusIndex++;
		if ( focusIndex>focusees.length-1 ) {
			if ( cyclick ) {
				focusIndex = 0;
			}
		}
		RuntimeEngine.getStage().focus = focusees[focusIndex].getFocusee();
		focusees[focusIndex].focus();
	}
	// }}}
	// {{{ public function previous() : Void
	/**
	 * focusIndex順にフォーカスを前へ移します。もし同じ数字のfocusIndexをもつオブジェクトが複数ある場合には、
	 * 配列に格納されている順番でフォーカスの移動先が決められます。
	 */
	public function previous() : Void
	{
		/* UXObjectのputEventメソッドにFocusEventイベントを投げます*/
		focusIndex--;
		if ( focusIndex<0 ) {
			if ( cyclick ) {
				focusIndex = focusees.length-1;
			}
		}
		RuntimeEngine.getStage().focus = focusees[focusIndex].getFocusee();
		focusees[focusIndex].focus();
	}
	// }}}
 	// {{{ public function setFocus( fs : UXObject ) : Void
	/**
	 * 指定されたオブジェクトが管理下にあれば、指定されたにオブジェクトにフォーカスを移します。
	 */
	public function setFocus( fs : UXObject ) : Void
	{
		/* UXObjectのputEventメソッドにFocusEventイベントを投げます*/
		//fs.putEvent( new FocusEvent() );
		if ( fs.focusManager==this ) {
			for ( i in 0...focusees.length ) {
				if ( fs==focusees[i] ) {
					RuntimeEngine.getStage().focus = focusees[i].getFocusee();
					focusees[i].focus();
				}
			}
		}
	}
	// }}}
 	// {{{ public function setFocusIndex( index : Int ) : Void
	/**
	 * 指定されたインデックスのオブジェクトにフォーカスを移します。
	 */
	public function setFocusIndex( index : Int ) : Void
	{
		if ( index>=0 && index<focusees.length ) {
			RuntimeEngine.getStage().focus = focusees[index].getFocusee();
			focusees[index].focus();
		}
	}
	// }}}
}
// }}}
